package ghostbanlistd;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Server extends Thread {
	public static final int DEFAULT_PORT = 5872;
	
	ServerSocket server;
	int numConnections;
	Database database;
	Bans bans;
	
	//config
	String bindAddressString;
	int maxConnections; //-1 for unlimited connections
	int port;
	
	public Server(Database database, Bans bans) {
		this.database = database;
		this.bans = bans;
		
		//read configuration values
		bindAddressString = Config.getString("server_bindaddress", null);
		maxConnections = Config.getInt("server_maxconnections", 0);
		port = Config.getInt("server_port", DEFAULT_PORT);
	}
	
	public void init() {
		Main.println("[Server] Initiating on port " + port);
		
		try {
			InetAddress bindAddress = null;
			
			if(bindAddressString != null) {
				try {
					bindAddress = InetAddress.getByName(bindAddressString);
				} catch(UnknownHostException uhe) {
					Main.println("[Server] Invalid bind address, ignoring: " + bindAddressString);
				}
			}
			
			if(bindAddress == null) {
				server = new ServerSocket(port);
			} else {
				//create server socket with backlog=50
				server = new ServerSocket(port, 50, bindAddress);
			}
		} catch(IOException ioe) {
			Main.println("[Server] Error while binding: " + ioe.getLocalizedMessage());
		}
	}
	
	public void removeConnection() {
		synchronized(this) {
			numConnections--;
		}
		
		Main.println("[Server] Removed connection, now at " + numConnections + " connections");
	}
	
	public void run() {
		while(true) {
			try {
				Socket socket = server.accept();
				
				if(maxConnections != 0 && numConnections >= maxConnections) {
					Main.println("[Server] Rejecting connection from " + socket.getInetAddress() + " due to limit");
					socket.close();
					continue;
				}
				
				synchronized(this) {
					numConnections++;
				}
				
				Main.println("[Server] New connection from " + socket.getInetAddress() + "; now at " + numConnections + " connections");
				BanConnection connection = new BanConnection(socket, this);
				connection.start();
			} catch(IOException ioe) {
				Main.println("[Server] Error while accepting connection: " + ioe.getLocalizedMessage());
			}
		}
	}
}
